package com.example.utils;

import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class DateUtil {

	private static final int FIRST_DAY = Calendar.MONDAY;
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

	public static SimpleDateFormat getSdf() {
		return sdf;
	}

	public static void setSdf(SimpleDateFormat sdf) {
		DateUtil.sdf = sdf;
	}

	private static void setToFirstDay(Calendar calendar) {
		while (calendar.get(Calendar.DAY_OF_WEEK) != FIRST_DAY) {
			calendar.add(Calendar.DATE, -1);
		}
	}

	private static String printDay(Calendar calendar) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 非空判断 --字符串不为空时为true 方法名： isNotEmpty <BR>
	 * 
	 * @param str
	 * @return boolean <BR>
	 */
	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	/**
	 * 空判断 --判断字符串为空时true 方法名： isEmpty <BR>
	 * 
	 * @param str
	 * @return boolean <BR>
	 */
	public static boolean isEmpty(String str) {
		return null == str || str.length() == 0 || "".equals(str) || "null".equals(str) || str.matches("\\s*");
	}

	/**
	 * 判断对象为空
	 * 
	 * @param obj 对象名
	 * @return 是否为空
	 */
	public static boolean isEmptyObj(Object obj) {
		if (obj == null) {
			return true;
		}
		if ((obj instanceof List)) {
			return ((List) obj).size() == 0;
		}
		if ((obj instanceof String)) {
			return ((String) obj).trim().equals("");
		}
		return false;
	}

	/**
	 * 判断对象不为空
	 * 
	 * @param obj 对象名
	 * @return 是否不为空
	 */
	public static boolean isNotEmptyObj(Object obj) {
		return !isEmptyObj(obj);
	}
	
	/**
	 * 获取当前计算机 系统时间 方法名： getSystemTime <BR>
	 * 创建人： Flycat <BR>
	 * 时间： 2015年11月10日-下午2:14:45 <BR>
	 * 
	 * @return String <BR>
	 * @since 1.0.0
	 */
	public static String getSystemTime() {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// System.out.println("当前系统时间为 ： "+formatter.format(date));
		return formatter.format(new Date());
	}

	public static String getSystemTime(String flag) {
		SimpleDateFormat formatter = null;
		if (flag.equals("0")) {
			formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 24小时制
		} else if (flag.equals("1")) {
			formatter = new SimpleDateFormat("yyyy-MM-dd");
		} else if (flag.equals("2")) {
			formatter = new SimpleDateFormat("HH:mm:ss"); // 24小时制
		} else if (flag.equals("3")) {
			formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
		} else if (flag.equals("4")) {
			formatter = new SimpleDateFormat("yyyyMMdd");
		} else if (flag.equals("5")) {
			formatter = new SimpleDateFormat("yyyyMMddhhmmss");
		} else {
			formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); // 24小时制
		}
		return formatter.format(new Date());
	}

	/**
	 * 传入时间格式
	 * 
	 * @param dateFormat
	 * @return
	 */
	public static String getDateTime(String dateFormat) {
		SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
		return formatter.format(new Date());
	}

	/**
	 * 将字符串转化为日期
	 * 
	 * @param timestr
	 * @return
	 */
	public static Date paraseStringToDate(String timestr) {
		Date date = null;
		Format f = new SimpleDateFormat("yyyy-MM-dd");
		try {
			date = (Date) f.parseObject(timestr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	private static Date getNext(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, 1);
		return calendar.getTime();
	}

	/**
	 * 获得当前日期
	 * 
	 * @return
	 */
	public static String getCurrentDate() {
		return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
	}

	/**
	 * 获得指定日期的前或后几天
	 * 
	 * @param specifiedDay
	 * @param num
	 * @return
	 */
	public static String getSpecifiedDay(String specifiedDay, int num) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int day = c.get(Calendar.DATE);
		c.set(Calendar.DATE, day + num);

		String dayStr = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return dayStr;
	}

	/**
	 * 获得指定日期的前或后几月
	 * 
	 * @param specifiedDay
	 * @param num
	 * @return
	 */
	public static String getSpecifiedMonth(String specifiedDay, int num) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int month = c.get(Calendar.MONTH);
		c.set(Calendar.MONTH, month + num);

		String monthStr = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return monthStr;
	}

	/**
	 * 获得指定日期的前或后几年
	 * 
	 * @param specifiedDay
	 * @param num
	 * @return
	 */
	public static String getSpecifiedYear(String specifiedDay, int num) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int year = c.get(Calendar.YEAR);
		c.set(Calendar.YEAR, year + num);

		String yearStr = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return yearStr;
	}

	/**
	 * 获得指定日期的前一天
	 * 
	 * @param specifiedDay
	 * @return
	 * @throws Exception
	 */
	public static String getSpecifiedDayBefore(String specifiedDay) {// 可以用new Date().toLocalString()传递参数
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int day = c.get(Calendar.DATE);
		c.set(Calendar.DATE, day - 1);

		String dayBefore = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return dayBefore;
	}

	/**
	 * 获得指定日期的后一天
	 * 
	 * @param specifiedDay
	 * @return
	 */
	public static String getSpecifiedDayAfter(String specifiedDay) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int day = c.get(Calendar.DATE);
		c.set(Calendar.DATE, day + 1);

		String dayAfter = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return dayAfter;
	}

	/**
	 * 获得指定日期的前一个月
	 * 
	 * @param specifiedDay
	 * @return
	 */
	public static String getSpecifiedMonthBefore(String specifiedDay) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int month = c.get(Calendar.MONTH);
		c.set(Calendar.MONTH, month - 1);

		String monthBefore = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return monthBefore;
	}

	/**
	 * 获得指定日期的后一个月
	 * 
	 * @param specifiedDay
	 * @return
	 */
	public static String getSpecifiedMonthAfter(String specifiedDay) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int month = c.get(Calendar.MONTH);
		c.set(Calendar.MONTH, month + 1);

		String monthAfter = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return monthAfter;
	}

	/**
	 * 获得指定日期的前一年
	 * 
	 * @param specifiedDay
	 * @return
	 */
	public static String getSpecifiedYearBefore(String specifiedDay) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int year = c.get(Calendar.YEAR);
		c.set(Calendar.YEAR, year - 1);

		String yearBefore = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return yearBefore;
	}

	/**
	 * 获得指定日期的后一年
	 * 
	 * @param specifiedDay
	 * @return
	 */
	public static String getSpecifiedYearAfter(String specifiedDay) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int year = c.get(Calendar.YEAR);
		c.set(Calendar.YEAR, year + 1);

		String yearAfter = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return yearAfter;
	}

	/**
	 * 获取当前月月初日期
	 * 
	 * @return
	 */
	public static String getMonthStart() {
		Date d = new Date();
		return sdf.format(getMonthStart(d));
	}

	/**
	 * 获取月末日期
	 * 
	 * @return
	 */
	public static String getMonthEnd() {
		Date d = new Date();
		return sdf.format(getMonthEnd(d));
	}

	/**
	 * 获取月初第一天 例：Thu Feb 01 00:00:00 CST 2018
	 * 
	 * @param date
	 * @return
	 */
	public static Date getMonthStart(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int index = calendar.get(Calendar.DAY_OF_MONTH);
		calendar.add(Calendar.DATE, (1 - index));
		return calendar.getTime();
	}

	/**
	 * 获取月末最后一天 例：Wed Feb 28 00:00:00 CST 2018
	 * 
	 * @param date
	 * @return
	 */
	public static Date getMonthEnd(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, 1);
		int index = calendar.get(Calendar.DAY_OF_MONTH);
		calendar.add(Calendar.DATE, (-index));
		return calendar.getTime();
	}

	/**
	 * 根据传入日期来获取一个月的开始时间 例：2018-02-01
	 * 
	 * @param d
	 * @return
	 */
	public static String getMonthStartStr(Date d) {
		return sdf.format(getMonthStart(d));
	}

	/**
	 * 根据传入时间获取一个月月末时间 例：2018-02-28
	 * 
	 * @param d
	 * @return
	 */
	public static String getMonthEndStr(Date d) {
		return sdf.format(getMonthEnd(d));
	}

	/**
	 * 获取当前月的所有日期
	 * 
	 * @return
	 */
	public static List<String> getAllDaysMonth() {
		List<String> lst = new ArrayList();
		Date d = new Date();
		System.out.println("月初：" + sdf.format(getMonthStart(d)));
		System.out.println("月末：" + sdf.format(getMonthEnd(d)));
		Date date = getMonthStart(d);
		Date monthEnd = getMonthEnd(d);
		while (!date.after(monthEnd)) {
			lst.add(sdf.format(date));
			date = getNext(date);
		}
		return lst;
	}

	/**
	 * 根据传入的日期获取所在月份所有日期
	 * 
	 * @param d
	 * @return
	 */
	public static List<String> getAllDaysMonthByDate(Date d) {
		List<String> lst = new ArrayList();
		Date date = getMonthStart(d);
		Date monthEnd = getMonthEnd(d);
		while (!date.after(monthEnd)) {
			lst.add(sdf.format(date));
			date = getNext(date);
		}
		return lst;
	}

	/**
	 * 根据日期来获取一周的第一天
	 * 
	 * @param d
	 * @return
	 */
	public static String getWeekStartDay(Date d) {
		Calendar c = Calendar.getInstance();
		List<String> lst = new ArrayList();
		c.setTime(d);
		setToFirstDay(c);
		for (int i = 0; i < 7; i++) {
			String day = printDay(c);
			lst.add(day);
			c.add(Calendar.DATE, 1);
		}
		return lst.get(0);
	}

	/**
	 * 根据日期来获取一周的最后一天
	 * 
	 * @param d
	 * @return
	 */
	public static String getWeekEndtDay(Date d) {
		Calendar c = Calendar.getInstance();
		List<String> lst = new ArrayList();
		c.setTime(d);
		setToFirstDay(c);
		for (int i = 0; i < 7; i++) {
			String day = printDay(c);
			lst.add(day);
			c.add(Calendar.DATE, 1);
		}
		return lst.get(6);
	}

	/**
	 * 获取其所在周的每一天
	 * 
	 * @return
	 */
	public static List<String> getALlweekDays() {
		List<String> lst = new ArrayList();
		Calendar calendar = Calendar.getInstance();
		setToFirstDay(calendar);
		for (int i = 0; i < 7; i++) {
			String day = printDay(calendar);
			lst.add(day);
			calendar.add(Calendar.DATE, 1);
		}
		return lst;
	}

	/**
	 * 根据指定日期来获取其所在周的每一天
	 * 
	 * @param d
	 * @return
	 */
	public static List<String> getAllweekDays(Date d) {
		Calendar c = Calendar.getInstance();
		List<String> lst = new ArrayList();
		c.setTime(d);
		setToFirstDay(c);
		for (int i = 0; i < 7; i++) {
			String day = printDay(c);
			lst.add(day);
			c.add(Calendar.DATE, 1);
		}
		return lst;
	}

	/**
	 * 得到完整时间戳
	 * 
	 * @param dateStr      时间
	 * @param dateFormat格式
	 * @return
	 * @throws ParseException
	 */
	public static long getStringToDateTime(String dateStr, String dateFormat) throws ParseException {
		// 注意format的格式要与日期String的格式相匹配
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Date date = sdf.parse(dateStr);
		return date.getTime();
	}

	/**
	 * 得到10位时间戳 日期格式字符串转换成时间戳
	 * 
	 * @param dateStr 字符串日期
	 * @param format  如：yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String getDateToTimeStamp(String dateStr, String format) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			return String.valueOf(sdf.parse(dateStr).getTime() / 1000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * Java将Unix时间戳转换成指定格式日期字符串
	 * 
	 * @param timestampString 时间戳 如："1473048265";
	 * @param formats         要格式化的格式 默认："yyyy-MM-dd HH:mm:ss";
	 *
	 * @return 返回结果 如："2016-09-05 16:06:42";
	 */
	public static String getTimeStampToDate(String timestampString, String formats) {
		if (DateUtil.isEmpty(formats))
			formats = "yyyy-MM-dd HH:mm:ss";
		Long timestamp = Long.parseLong(timestampString) * 1000;
		String date = new SimpleDateFormat(formats, Locale.CHINA).format(new Date(timestamp));
		return date;
	}

	/**
	 * 取得当前时间戳（精确到秒）
	 *
	 * @return nowTimeStamp
	 */
	public static String getNowTimeStamp() {
		long time = System.currentTimeMillis();
		String nowTimeStamp = String.valueOf(time / 1000);
		return nowTimeStamp;
	}

	public static void main(String[] args) throws Exception {
//      String specifiedDay = "2018-02-28";	
//      
//      System.out.println("当前日期:\t"+specifiedDay);							//当前日期
//      System.out.println("前一天:\t"+getSpecifiedDayBefore(specifiedDay));		//前一天
//      System.out.println("后一天:\t"+getSpecifiedDayAfter(specifiedDay));		//后一天
//      System.out.println("前一月:\t"+getSpecifiedMonthBefore(specifiedDay));	//前一月
//      System.out.println("后一月:\t"+getSpecifiedMonthAfter(specifiedDay));	//后一月        
//      System.out.println("前一年:\t"+getSpecifiedYearBefore(specifiedDay));	//前一年
//      System.out.println("后一年:\t"+getSpecifiedYearAfter(specifiedDay));		//后一年      
//      
//      System.out.println(getSpecifiedDay(FileUtils.getDateTime("yyyy-MM-dd"), 0));	//指定前或后几天
//      System.out.println(getSpecifiedDay(FileUtils.getDateTime("yyyy-MM-dd"), 1));	//指定前或后几天
//      System.out.println(getSpecifiedDay(FileUtils.getDateTime("yyyy-MM-dd"), -1));	//指定前或后几天
//      System.out.println(getSpecifiedDay(FileUtils.getDateTime("yyyy-MM-dd"), -7));	//指定前或后几天
//      System.out.println(getSpecifiedMonth(FileUtils.getDateTime("yyyy-MM-dd"), 1));	//指定前或后几月
//      System.out.println(getSpecifiedYear(FileUtils.getDateTime("yyyy-MM-dd"), -2));	//指定前或后几年
//      
//      
//      System.out.println(getMonthStart());			//获取当前日期的月初
//      System.out.println(getMonthEnd());			//获取当前日期的月末
//      System.out.println(getALlweekDays());			//获取当前周的所有天 		例：[2018-02-26, 2018-02-27, 2018-02-28, 2018-03-01, 2018-03-02, 2018-03-03, 2018-03-04]
//      System.out.println(getAllDaysMonth());		//获取当前月的所有日期
//      
//      
//      Date d = sdf.parse("2018-02-27");
//      System.out.println(getMonthStartStr(d));		//获取指定日期的月初		例：2018-03-01
//      System.out.println(getMonthEndStr(d));		//获取指定日期的月末		例：2018-03-31
//      System.out.println(getMonthStart(d));			//获取指定日期的月初		例：Thu Mar 01 00:00:00 CST 2018
//      System.out.println(getMonthEnd(d));			//获取指定日期的月末		例：Sat Mar 31 00:00:00 CST 2018 
//      System.out.println(getAllDaysMonthByDate(d));	//获取指定月的所有日期
//      
//      System.out.println(getWeekStartDay(d));		//根据指定日期来获取一周的第一天		例：2018-02-26
//      System.out.println(getWeekEndtDay(d));		//根据指定日期来获取一周的最后一天	例：2018-03-04
//      System.out.println(getAllweekDays(d));		//根据指定日期来获取其所在周的每一天	例：[2018-02-26, 2018-02-27, 2018-02-28, 2018-03-01, 2018-03-02, 2018-03-03, 2018-03-04]

		System.out.println(getNowTimeStamp());// 获取当前10位时间戳
		System.out.println(getStringToDateTime("2018-04-14", "yyyy-MM-dd")); // 获取指定日期的完整时间戳
		System.out.println(getDateToTimeStamp("2018-04-14", "yyyy-MM-dd")); // 获取指定日期的10位时间戳
		System.out.println(getTimeStampToDate("1523635200", "yyyy-MM-dd")); // 时间戳转回日期
		System.out.println(getTimeStampToDate("1524019429", "yyyy-MM-dd HH:mm:ss"));
		DateUtil.getNowTimeStamp();
	}

}